﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;

namespace SolutionFactory
{
    public class WriteFiles
    {
        /// <summary>
        /// 程序集信息
        /// </summary>
        /// <param name="assemblyPath"></param>
        public static void WriteAssemblyInfo(string assemblyPath,string guid)
        {
            string assemblyInfo = File.ReadAllText("ResourceFile/Template/AssemblyInfo.txt");
            assemblyInfo = assemblyInfo.Replace("[assembly: Guid(\"", "[assembly: Guid(\"" + guid);
            TextWriter tw = new StreamWriter(new FileStream(assemblyPath + "/AssemblyInfo.cs", FileMode.Create, FileAccess.Write));
            tw.WriteLine(assemblyInfo);
            tw.Close();
        }
        /// <summary>
        /// 工程文件
        /// </summary>
        public static void WriteCsprojFile(LibraryClassInfo libInfo)
        {
            string assemblyInfo = File.ReadAllText("ResourceFile/Template/CsprojTemplate.txt");
            assemblyInfo = assemblyInfo.Replace("<ProjectGuid></ProjectGuid>", "<ProjectGuid>"+libInfo.Guid+"</ProjectGuid>");
            assemblyInfo = assemblyInfo.Replace("<RootNamespace></RootNamespace>", "<RootNamespace>" + libInfo.NameSpace + "</RootNamespace>");
            assemblyInfo = assemblyInfo.Replace("<AssemblyName></AssemblyName>", "<AssemblyName>" + libInfo.NameSpace + "</AssemblyName>");
            string compiles = "";
            for (int i = 0; i < libInfo.Classes.Length; i++)
            {
                compiles += "<Compile Include=\"" + libInfo.Classes[i] + "\" />" + "\r\n";
            }
            //如果是数据库操作类库，需要引用实体类库和实体工厂类库，Configuration引用及包含DBHelper
            if (libInfo.NameSpace.EndsWith("DataBaseAccess"))
            {
                //引用其他类库
                string projectReference = "";
                projectReference +=string.Format("<ProjectReference Include=\"..\\{0}\\{0}.csproj\">",GlobalProperty.EntityFactoryLibraryClassInfo.NameSpace);
                projectReference += "    <Project>{" + GlobalProperty.EntityFactoryLibraryClassInfo.Guid+ "}</Project>";
                projectReference += "       <Name>"+GlobalProperty.EntityFactoryLibraryClassInfo.NameSpace+"</Name>";
                projectReference += "</ProjectReference>";

                projectReference += string.Format("<ProjectReference Include=\"..\\{0}\\{0}.csproj\">", GlobalProperty.ModelLibraryClassInfo.NameSpace);
                projectReference += "    <Project>{" + GlobalProperty.ModelLibraryClassInfo.Guid + "}</Project>";
                projectReference += "       <Name>" + GlobalProperty.ModelLibraryClassInfo.NameSpace + "</Name>";
                projectReference += "</ProjectReference>";

                assemblyInfo = assemblyInfo.Replace("<ProjectReference></ProjectReference>", projectReference);
                string config = " <Reference Include=\"System\" />";
                config+="<Reference Include=\"System.configuration\" />";
    
                assemblyInfo = assemblyInfo.Replace("<Reference Include=\"System\" />", config);
                //dbhelper
                compiles += "<Compile Include=\"DBHelper\\DBHelper.cs\" />" + "\r\n";
            }
            //如果是实体工厂类库，引用Model
            if (libInfo.NameSpace.EndsWith("EntityFactory"))
            {
                //引用其他类库
                string projectReference = "";
                projectReference += string.Format("<ProjectReference Include=\"..\\{0}\\{0}.csproj\">", GlobalProperty.ModelLibraryClassInfo.NameSpace);
                projectReference += "    <Project>{" + GlobalProperty.ModelLibraryClassInfo.Guid + "}</Project>";
                projectReference += "       <Name>" + GlobalProperty.ModelLibraryClassInfo.NameSpace + "</Name>";
                projectReference += "</ProjectReference>";

                assemblyInfo = assemblyInfo.Replace("<ProjectReference></ProjectReference>", projectReference);
            }
            //如果是实体类库去掉引用
            if (libInfo.NameSpace.EndsWith("Model"))
            {
                //引用其他类库
                string projectReference = "";

                assemblyInfo = assemblyInfo.Replace("<ProjectReference></ProjectReference>", projectReference);
            }
            assemblyInfo = assemblyInfo.Replace("<Compile></Compile>", compiles);
            TextWriter tw = new StreamWriter(new FileStream(libInfo.FloderPath+ "/" + libInfo.NameSpace+".csproj", FileMode.Create, FileAccess.Write));
            tw.WriteLine(assemblyInfo);
            tw.Close();
        }
        /// <summary>
        /// 解决方案文件
        /// </summary>
        public static void WriteSolutionFile()
        {
            TextWriter tw = new StreamWriter(new FileStream(GlobalProperty.SolutionFloderPath +"/" + GlobalProperty.SolutionName+".sln", FileMode.Create, FileAccess.Write));
            tw.WriteLine("Microsoft Visual Studio Solution File, Format Version 11.00");
            tw.WriteLine("# Visual Studio 2010");
            List<LibraryClassInfo> list = new List<LibraryClassInfo>();
            list.Add(GlobalProperty.ModelLibraryClassInfo);
            list.Add(GlobalProperty.EntityFactoryLibraryClassInfo);
            list.Add(GlobalProperty.DataBaseAccessLibraryClassInfo);
            foreach (LibraryClassInfo item in list)
            {
                tw.WriteLine("Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"" + item.NameSpace + "\", \"" + item.NameSpace + "\\" + item.NameSpace + ".csproj\", \"{" + item.Guid + "}\"");
                tw.WriteLine("EndProject");
            }
            tw.Close();
        }
        /// <summary>
        /// 输出实体类.cs文件
        /// </summary>
        /// <param name="fields">字段名称，字段类型</param>
        /// <param name="entityName">实体名称</param>
        public static void WriteEntityFiles()
        {
            foreach (var entity in GlobalProperty.entitysInfo)
            {
                TextWriter tw = new StreamWriter(new FileStream(GlobalProperty.ModelLibraryClassInfo.FloderPath + "/" + entity.ModelClassName+".cs", FileMode.Create, FileAccess.Write));
                tw.WriteLine("using System;");
                tw.WriteLine("using System.Text;");
                tw.WriteLine("\r\n");
                tw.WriteLine("namespace " + GlobalProperty.SolutionName + ".Model");
                tw.WriteLine("{");

                WriteClassDescription(tw, entity.Description + "实体模型类");

                tw.WriteLine("\tpublic class " + entity.ModelClassName);
                tw.WriteLine("\t{");

                foreach (var item in entity.Fields)
                {
                    WriteFieldDescription(tw, item.Description);
                    string str = string.Format("\t\tpublic {0} {1} {2}", item.TypeName, item.FieldName, "{ get; set; }");
                    tw.WriteLine(str);
                }

                tw.WriteLine("\t}");
                tw.WriteLine("}");
                tw.Close();
            }
        }
        /// <summary>
        /// 组装实体类
        /// </summary>
        public static void WriteBuildEntity()
        {
            foreach (var entity in GlobalProperty.entitysInfo)
            {
                TextWriter tw = new StreamWriter(new FileStream(GlobalProperty.EntityFactoryLibraryClassInfo.FloderPath + "/" + entity.ClassName + "EntityFactory.cs", FileMode.Create, FileAccess.Write));
                tw.WriteLine("using System;");
                tw.WriteLine("using System.Text;");
                tw.WriteLine("using System.Data;");
                tw.WriteLine("using " + GlobalProperty.ModelLibraryClassInfo.NameSpace + ";");
                tw.WriteLine("\r\n");

                tw.WriteLine("namespace " + GlobalProperty.EntityFactoryLibraryClassInfo.NameSpace);
                tw.WriteLine("{");
                tw.WriteLine("\tpublic class " + entity.ClassName + "EntityFactory");
                tw.WriteLine("\t{");
                WriteFunctionDescription(tw, "根据IDataReader组装" + entity.Description + "实体模型","实体模型");
                tw.WriteLine("\t\tpublic static " + entity.ModelClassName + " Build" + entity.ClassName + "Entity(IDataReader reader)");
                tw.WriteLine("\t\t{");
                tw.WriteLine(string.Format("\t\t\t{0} entity = new {0}();", entity.ModelClassName));
                foreach (var field in entity.Fields)
                {
                    tw.WriteLine("\t\t\tif (reader[" + "\"" + field.TableColumnName + "\"" + "] != DBNull.Value)");
                    tw.WriteLine("\t\t\t\tentity." + field.FieldName + " = Convert.To" + field.TypeName + "(reader[" + "\"" + field.TableColumnName + "\"" + "]);");
                }
                tw.WriteLine("\t\t\treturn entity;");
                tw.WriteLine("\t\t}");
                tw.WriteLine("\t}");
                tw.WriteLine("}");
                tw.Close();
            }
        }
        /// <summary>
        /// 数据库操作
        /// </summary>
        public static void WriteDBAccess()
        {
            //DBHelper
            InitDBHelper();
            foreach (EntityClassInfo entity in GlobalProperty.entitysInfo)
            {
                //写入文件信息
                TextWriter tw = new StreamWriter(new FileStream(GlobalProperty.DataBaseAccessLibraryClassInfo.FloderPath + "/" + entity.ClassName + "DataBaseAccess.cs", FileMode.Create, FileAccess.Write));
                tw.WriteLine("using System;");
                tw.WriteLine("using System.Text;");
                tw.WriteLine("using System.Data;");
                tw.WriteLine("using System.Collections.Generic;");
                tw.WriteLine("using SolutionFactory.DBAccess;");
                tw.WriteLine("using " + GlobalProperty.ModelLibraryClassInfo.NameSpace + ";");
                tw.WriteLine("using " + GlobalProperty.EntityFactoryLibraryClassInfo.NameSpace + ";");
                tw.WriteLine("\r\n");

                tw.WriteLine("namespace " + GlobalProperty.DataBaseAccessLibraryClassInfo.NameSpace);
                tw.WriteLine("{");
                tw.WriteLine("\tpublic class " + entity.ClassName + "DataBaseAccess");
                tw.WriteLine("\t{");
                #region 添加
                WriteFunctionDescription(tw, "根据实体模型添加数据", "受影响的行数");
                tw.WriteLine(string.Format("\t\tpublic int Add{0}({1} entity)", entity.ClassName,entity.ModelClassName));
                tw.WriteLine("\t\t{");
                #region sql语句
                string insertSql = "INSERT INTO " + entity.TableName + " (";
                string valueSql = "\r\n\t\t\t\t\tVALUES (";
                string paraSql = "\r\n\t\t\t\t\t";
                int i=0;
                foreach (var item in entity.Fields)
                {
                    //非主键
                    if (item.TableColumnName!=entity.PrimaryKey)
                    {
                        insertSql += "[" + item.TableColumnName + "], ";
                        valueSql += "'{" + i + "}'" + ", ";
                        paraSql += "," + "entity." + item.FieldName;
                        i++;
                    }
                }
                if (insertSql.EndsWith(", "))
                    insertSql = insertSql.Substring(0, insertSql.Length - 2);
                if (valueSql.EndsWith(", "))
                    valueSql = valueSql.Substring(0, valueSql.Length - 2);
                insertSql += ")";
                valueSql += ")\"";
                string addSql = "String.Format(@\"" + insertSql + valueSql + paraSql + ");";
                #endregion
                tw.WriteLine("\t\t\tstring addSql = " + addSql);
                tw.WriteLine("\t\t\treturn DBHelper.ExecuteNonQuery(addSql);");
                tw.WriteLine("\t\t}");
                tw.WriteLine("\r\n");
                #endregion
                #region 删除
                WriteFunctionDescription(tw, "根据主键删除数据", "受影响的行数");
                tw.WriteLine(string.Format("\t\tpublic int Deleta{0}ByPrimaryKey(int PrimaryKeyId)", entity.ClassName));
                tw.WriteLine("\t\t{");
                string formateSql = string.Format("string delSql = \"DELETE FROM {0} WHERE {1} = \" + {2} ;", entity.TableName, entity.PrimaryKey, "PrimaryKeyId");
                tw.WriteLine("\t\t\t" + formateSql);
                tw.WriteLine("\t\t\treturn DBHelper.ExecuteNonQuery(delSql);");
                tw.WriteLine("\t\t}");
                tw.WriteLine("\r\n");
                #endregion
                #region 修改
                WriteFunctionDescription(tw, "根据实体模型修改数据", "受影响的行数");
                tw.WriteLine(string.Format("\t\tpublic int Update{0}({1} entity)", entity.ClassName, entity.ModelClassName));
                tw.WriteLine("\t\t{");
                #region sql语句
                string updateSql = "UPDATE " + entity.TableName + " SET ";
                string setSql = "";
                string upWhereSql = "";
                string fields = "\"\r\n\t\t\t\t\t";
                i = 0;
                string primaryKeyField = "";
                foreach (var item in entity.Fields)
                {
                    //非主键
                    if (item.TableColumnName!=entity.PrimaryKey)
                    {
                        setSql += item.TableColumnName + " = '{" + i + "}'" + ", ";
                        fields += ",entity."+item.FieldName;
                        i++;
                    }
                    else
                    {
                        primaryKeyField = item.FieldName;
                    }
                }
                //条件
                upWhereSql = " WHERE " + entity.PrimaryKey + "={" + i + "}";
                fields += ",entity." + primaryKeyField;

                if (setSql.EndsWith(", "))
                    setSql = setSql.Substring(0, setSql.Length - 2);

                string exeUpdateSql = "String.Format(@\"" + updateSql + setSql + upWhereSql + fields + ");";
                #endregion
                tw.WriteLine("\t\t\tstring updateSql = " + exeUpdateSql);
                tw.WriteLine("\t\t\treturn DBHelper.ExecuteNonQuery(updateSql);");
                tw.WriteLine("\t\t}");
                tw.WriteLine("\r\n");
                #endregion
                #region 查询
                //分页查询
                WriteFunctionDescription(tw, "分页查询", "\t\t/// <param name=\"pageIndex\">从0开始的页数</param>\r\n\t\t/// <param name=\"pageSize\">页面大小</param>", "实体模型的List泛型集合");
                tw.WriteLine(string.Format("\t\tpublic List<{0}> Select{1}ToPage(int pageIndex,int pageSize)",entity.ModelClassName, entity.ClassName));
                tw.WriteLine("\t\t{");
                string pageSql = "string pageSql = string.Format(@\"";
                string topSql = @"SELECT	TOP ({0}) * FROM {1}
                    WHERE ({2} > ISNULL((SELECT MAX ({2}) FROM ( SELECT TOP ({3}) {2} FROM {1} ORDER BY {2} DESC ) AS T ),0) )
                    ORDER BY {2} DESC" + "\"";
                string pageParaSql="";
                pageParaSql += ",pageSize";
                pageParaSql += ",\"" + entity.TableName + "\"";
                pageParaSql += ",\"" + entity.PrimaryKey + "\"";
                pageParaSql += ",pageIndex * pageSize);";
                pageSql = pageSql + topSql + pageParaSql;
                tw.WriteLine("\t\t\t" + pageSql);
                tw.WriteLine(string.Format("\t\t\tList<{0}> list = new List<{0}>();", entity.ModelClassName));
                tw.WriteLine("\t\t\tusing (IDataReader reader = DBHelper.ExecuteReader(pageSql))");
                tw.WriteLine("\t\t\t{");
                tw.WriteLine("\t\t\t\twhile (reader.Read())");
                tw.WriteLine("\t\t\t\t{");
                tw.WriteLine(string.Format("\t\t\t\t\t{0} entity = {1}EntityFactory.Build{1}Entity(reader);",entity.ModelClassName,entity.ClassName));
                tw.WriteLine("\t\t\t\t\tlist.Add(entity);");
                tw.WriteLine("\t\t\t\t}");
                tw.WriteLine("\t\t\t}");
                tw.WriteLine("\t\t\treturn list;");
                tw.WriteLine("\t\t}");
                tw.WriteLine("\r\n");
                //条件查询

                WriteFunctionDescription(tw, "按条件查询", "\t\t/// <param name=\"where\">条件sql语句，带where关键字</param>", "实体模型的List泛型集合");
                tw.WriteLine(string.Format("\t\tpublic List<{0}> Select{1}ByWhere(string where)", entity.ModelClassName, entity.ClassName));
                tw.WriteLine("\t\t{");
                string whereSql = string.Format("string whereSql = \"SELECT * FROM {0} \" + where;", entity.TableName);
                tw.WriteLine("\t\t\t" + whereSql);
                tw.WriteLine(string.Format("\t\t\tList<{0}> list = new List<{0}>();", entity.ModelClassName));
                tw.WriteLine("\t\t\tusing (IDataReader reader = DBHelper.ExecuteReader(whereSql))");
                tw.WriteLine("\t\t\t{");
                tw.WriteLine("\t\t\t\twhile (reader.Read())");
                tw.WriteLine("\t\t\t\t{");
                tw.WriteLine(string.Format("\t\t\t\t\t{0} entity = {1}EntityFactory.Build{1}Entity(reader);", entity.ModelClassName, entity.ClassName));
                tw.WriteLine("\t\t\t\t\tlist.Add(entity);");
                tw.WriteLine("\t\t\t\t}");
                tw.WriteLine("\t\t\t}");
                tw.WriteLine("\t\t\treturn list;");
                tw.WriteLine("\t\t}");
                tw.WriteLine("\r\n");
                #endregion
                tw.WriteLine("\t}");
                tw.WriteLine("}");
                tw.Close();

            }
        }
        /// <summary>
        /// 准备dbhelper
        /// </summary>
        private static void InitDBHelper()
        {
            string DBHelper = File.ReadAllText("ResourceFile/DBHelper/DBHelper.cs");
            TextWriter tw = new StreamWriter(new FileStream(GlobalProperty.DataBaseAccessLibraryClassInfo.FloderPath + "/DBHelper/" + "DBHelper.cs", FileMode.Create, FileAccess.Write));
            tw.WriteLine(DBHelper);
            tw.Close();

        }
        /// <summary>
        /// 字段描述
        /// </summary>
        private static void WriteFieldDescription(TextWriter tw, string description)
        {
            tw.WriteLine("\t\t/// <summary>");
            tw.WriteLine("\t\t/// " + description);
            tw.WriteLine("\t\t/// </summary>");
        }
        /// <summary>
        /// 类描述
        /// </summary>
        private static void WriteClassDescription(TextWriter tw, string description)
        {
            tw.WriteLine("\t/// <summary>");
            tw.WriteLine("\t/// " + description);
            tw.WriteLine("\t/// </summary>");
        }
        /// <summary>
        /// 方法描述
        /// </summary>
        private static void WriteFunctionDescription(TextWriter tw, string description,string returnDescript)
        {
            tw.WriteLine("\t\t/// <summary>");
            tw.WriteLine("\t\t/// " + description);
            tw.WriteLine("\t\t/// </summary>");
            tw.WriteLine("\t\t/// <returns>" + returnDescript + "</returns>");
        }
        /// <summary>
        /// 方法描述
        /// </summary>
        private static void WriteFunctionDescription(TextWriter tw, string description,string paramStr, string returnDescript)
        {
            tw.WriteLine("\t\t/// <summary>");
            tw.WriteLine("\t\t/// " + description);
            tw.WriteLine("\t\t/// </summary>");
            tw.WriteLine(paramStr);
            tw.WriteLine("\t\t/// <returns>" + returnDescript + "</returns>");
        }
    }
}
